import React, { useState, useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'
import { useNavigate } from 'react-router-dom'
import TopNavbar from '../../components/TopNavbar'
import ErrorBoundary from '../../components/ErrorBoundary'
import { uploadFile } from '../../services/uploadService'
import aiService from '../../services/aiService'
import styles from './index.module.css'

const CustomerService = () => {
  const navigate = useNavigate()
  const [inputValue, setInputValue] = useState('')
  const [chatHistory, setChatHistory] = useState(() => {
    try {
      const saved = localStorage.getItem('customerServiceChatHistory')
      return saved ? JSON.parse(saved) : []
    } catch {
      return []
    }
  })
  const [isLoading, setIsLoading] = useState(false)
  const [isRecording, setIsRecording] = useState(false)
  const mediaRecorderRef = useRef(null)
  const recordedChunksRef = useRef([])
  const [isVoiceMode, setIsVoiceMode] = useState(false)
  const [showPlusMenu, setShowPlusMenu] = useState(false)
  const [showEmojiMenu, setShowEmojiMenu] = useState(false)
  const [viewingImage, setViewingImage] = useState(null)
  const [scale, setScale] = useState(1)
  const [position, setPosition] = useState({ x: 0, y: 0 })
  const [heartbeatStatus, setHeartbeatStatus] = useState('unknown') // 'unknown', 'ok', 'error'
  const [connectionTip, setConnectionTip] = useState('')
  const chatEndRef = useRef(null)
  const fileInputRef = useRef(null)
  const folderInputRef = useRef(null)
  const prevHeartbeatStatusRef = useRef('unknown')
  const isMountedRef = useRef(false)
  const heartbeatTimeoutRef = useRef(null)

  const scrollToBottom = () => {
    chatEndRef.current?.scrollIntoView({ behavior: 'smooth' })
  }

  useEffect(() => {
    scrollToBottom()
    try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(chatHistory)) } catch { /* noop */ }
  }, [chatHistory])

  // 心跳检测函数
  const performHeartbeat = async () => {
    try {
      const label = `AI Heartbeat ${new Date().toISOString()}`
      console.time(label)
      const result = await aiService.heartbeat()
      console.timeEnd(label)
      console.count('AI心跳次数')
      setHeartbeatStatus(result.status)
      // 显示“连接成功”提示：当状态从非 ok 变为 ok 时
      if (result.status === 'ok' && prevHeartbeatStatusRef.current !== 'ok') {
        setConnectionTip('连接成功')
        setTimeout(() => setConnectionTip(''), 2000)
      }
      prevHeartbeatStatusRef.current = result.status
      console.log('[AI 心跳结果]', { 状态: result.status, 时间: new Date(result.timestamp || Date.now()).toLocaleString() })
    } catch {
      setHeartbeatStatus('error')
      prevHeartbeatStatusRef.current = 'error'
      console.log('[AI 心跳结果]', { 状态: 'error', 时间: new Date().toLocaleString() })
    }
  }

  // 启动心跳检测
  useEffect(() => {
    isMountedRef.current = true
    const schedule = () => {
      const interval = document.hidden ? 60000 : 15000
      heartbeatTimeoutRef.current = setTimeout(async () => {
        if (!isMountedRef.current) return
        await performHeartbeat()
        if (!isMountedRef.current) return
        schedule()
      }, interval)
    }
    // 初次心跳
    performHeartbeat().then(() => {
      if (!isMountedRef.current) return
      schedule()
    })

    const onVisibilityChange = () => {
      if (heartbeatTimeoutRef.current) clearTimeout(heartbeatTimeoutRef.current)
      console.info(`[AI 心跳] 页面可见性: ${document.hidden ? '隐藏' : '可见'}`)
      schedule()
    }
    document.addEventListener('visibilitychange', onVisibilityChange)

    return () => {
      isMountedRef.current = false
      if (heartbeatTimeoutRef.current) {
        clearTimeout(heartbeatTimeoutRef.current)
        heartbeatTimeoutRef.current = null
      }
      document.removeEventListener('visibilitychange', onVisibilityChange)
    }
  }, [])

  useEffect(() => {
    // hydrate
    try {
      const raw = localStorage.getItem('customerServiceChatHistory')
      if (raw) setChatHistory(JSON.parse(raw))
    } catch { /* noop */ }
  }, [])

  const handleClearChat = () => {
    setChatHistory([])
    localStorage.removeItem('customerServiceChatHistory')
  }

  const handleSendMessage = async () => {
    if (!inputValue.trim() || isLoading) return

    const userMessage = {
      type: 'user',
      content: inputValue,
      timestamp: new Date()
    }

    setChatHistory(prev => {
      const newHistory = [...prev, userMessage]
      try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
      return newHistory
    })
    setInputValue('')
    setIsLoading(true)

    try {
      const contextForAI = chatHistory
        .filter(m => (m.type === 'user' || m.type === 'ai') && typeof m.content === 'string')
        .map(m => ({ type: m.type === 'ai' ? 'assistant' : 'user', content: m.content }))

      // 流式回显
      let tempIdx = null
      await aiService.streamMessage(userMessage.content, contextForAI, ({ text, aggregated, done }) => {
        if (done) return
        if (!text && !aggregated) return
        setChatHistory(prev => {
          const list = [...prev]
          if (tempIdx == null) {
            const aiMsg = { type: 'ai', content: text || aggregated || '', timestamp: new Date() }
            list.push(aiMsg)
            tempIdx = list.length - 1
          } else {
            list[tempIdx] = { ...list[tempIdx], content: aggregated }
          }
          try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(list)) } catch { /* noop */ }
          return list
        })
      })
    } catch {
      const errorMessage = {
        type: 'ai',
        content: '抱歉，发生异常。',
        timestamp: new Date()
      }
      setChatHistory(prev => {
        const newHistory = [...prev, errorMessage]
        try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
        return newHistory
      })
    } finally {
      setIsLoading(false)
    }
  }

  // 推荐问题与快捷操作（按效果图）
  const suggestedQuestions = [
    '如何绑定电子就诊卡?',
    '门诊挂号如何操作?',
    '处方能在手机上缴费吗?',
    '门诊挂号能使用医保支付吗?',
    '住院预交金能给亲友充值吗?',
    '如何在手机上进行门诊挂号退费?'
  ]
  const suggestedActions = [
    { icon: '🗓️', text: '门诊挂号', action: () => navigate('/register') },
    { icon: '💳', text: '门诊缴费', action: () => navigate('/payment') },
    { icon: '📋', text: '门诊报告', action: () => navigate('/records') }
  ]
  const refreshQuestions = () => { /* 预留刷新 */ }
  const handleQuestionClick = (q) => {
    setInputValue(q)
    setTimeout(() => { handleSendMessage() }, 100)
  }

  // 发送图片
  const handleUpload = async (e) => {
    const file = e.target.files?.[0]
    if (!file) return
    try {
      const MAX_SIZE = 5 * 1024 * 1024
      if (file.size > MAX_SIZE) throw new Error('文件大小超过5MB限制')
      const res = await uploadFile(file, () => { /* 不展示进度消息 */ })

      setChatHistory(prev => {
        const newHistory = [...prev, { type: 'user', url: res.url, isImage: res.type?.startsWith('image/'), timestamp: new Date() }]
        try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
        return newHistory
      })
    } catch (err) {
      setChatHistory(prev => {
        const newHistory = [...prev, { type: 'user', content: `上传失败: ${err.message}`, timestamp: new Date() }]
        try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
        return newHistory
      })
    } finally {
      if (fileInputRef.current) fileInputRef.current.value = ''
    }
  }

  // 发送语音（本地录音）
  const handleVoiceInput = async () => {
    if (isRecording) {
      try {
        mediaRecorderRef.current?.stop()
        setIsRecording(false)
      } catch {
        setIsRecording(false)
      }
      return
    }

    if (!isRecording) {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
        const mediaRecorder = new MediaRecorder(stream)
        recordedChunksRef.current = []
        mediaRecorder.ondataavailable = (e) => {
          if (e.data && e.data.size > 0) recordedChunksRef.current.push(e.data)
        }
        mediaRecorder.onstop = () => {
          const blob = new Blob(recordedChunksRef.current, { type: 'audio/webm' })
          const url = URL.createObjectURL(blob)
          setChatHistory(prev => {
            const newHistory = [...prev, { type: 'user', url, isAudio: true, timestamp: new Date() }]
            try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
            return newHistory
          })
        }
        mediaRecorder.start()
        mediaRecorderRef.current = mediaRecorder
        setIsRecording(true)
      } catch {
        setIsRecording(false)
      }
    }
  }

  // 发送文件夹
  const handleFolderUpload = async (e) => {
    const files = Array.from(e.target.files || [])
    if (files.length === 0) return
    
    try {
      for (const file of files) {
        const MAX_SIZE = 5 * 1024 * 1024
        if (file.size > MAX_SIZE) {
          setChatHistory(prev => {
            const newHistory = [...prev, { type: 'user', content: `文件 ${file.name} 超过5MB限制`, timestamp: new Date() }]
            try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
            return newHistory
          })
          continue
        }
        
        const res = await uploadFile(file, () => {})
        setChatHistory(prev => {
          const newHistory = [...prev, { type: 'user', url: res.url, isImage: res.type?.startsWith('image/'), timestamp: new Date() }]
          try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
          return newHistory
        })
      }
    } catch (err) {
      setChatHistory(prev => {
        const newHistory = [...prev, { type: 'user', content: `文件夹上传失败: ${err.message}`, timestamp: new Date() }]
        try { localStorage.setItem('customerServiceChatHistory', JSON.stringify(newHistory)) } catch { /* noop */ }
        return newHistory
      })
    } finally {
      if (folderInputRef.current) folderInputRef.current.value = ''
    }
  }

  // 发送表情
  const handleEmojiClick = (emoji) => {
    setInputValue(prev => prev + emoji)
    setShowEmojiMenu(false)
  }

  // 切换语音/键盘模式
  const toggleVoiceMode = () => {
    setIsVoiceMode(!isVoiceMode)
    if (isVoiceMode) {
      setInputValue('')
    }
    // 切换模式时收起所有菜单
    setShowPlusMenu(false)
    setShowEmojiMenu(false)
  }

  // 输入框获焦时收起所有菜单
  const handleInputFocus = () => {
    setShowPlusMenu(false)
    setShowEmojiMenu(false)
  }

  // 点击外部区域时收起菜单
  useEffect(() => {
    const handleClickOutside = (event) => {
      if (!event.target.closest(`.${styles.inputContainer}`)) {
        setShowPlusMenu(false)
        setShowEmojiMenu(false)
      }
    }

    document.addEventListener('mousedown', handleClickOutside)
    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
    }
  }, [])

  return (
    <div className={styles.customerServicePage}>
      {/* 顶部导航（仅展示） */}
      <ErrorBoundary>
        <TopNavbar
          title="智能客服"
          showBack={true}
          onBack={() => navigate(-1)}
          rightContent={
            <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
              <div 
                style={{ 
                  width: '8px', 
                  height: '8px', 
                  borderRadius: '50%', 
                  backgroundColor: heartbeatStatus === 'ok' ? '#52c41a' : heartbeatStatus === 'error' ? '#ff4d4f' : '#faad14',
                  cursor: 'pointer'
                }} 
                title={`AI服务状态: ${heartbeatStatus === 'ok' ? '正常' : heartbeatStatus === 'error' ? '异常' : '检测中'}`}
                onClick={performHeartbeat}
              />
              {heartbeatStatus === 'unknown' && (
                <span style={{ color: '#faad14', fontSize: 12 }}>连接中···</span>
              )}
              {heartbeatStatus === 'error' && (
                <span style={{ color: '#ff4d4f', fontSize: 12 }}>已掉线</span>
              )}
              {connectionTip && (
                <span style={{ color: '#52c41a', fontSize: 12 }}>{connectionTip}</span>
              )}
              <span style={{ cursor: 'pointer' }} onClick={handleClearChat}>清空</span>
            </div>
          }
        />
      </ErrorBoundary>

      {/* 聊天内容区域 */}
      <div className={styles.chatContainer}>
        {/* 介绍消息 */}
        <div className={styles.messageGroup}>
          <div className={styles.messageBubble}>
            <div className={styles.messageText}>HI, 我是专属智能客服, 土豆炖蘑菇</div>
            <div className={styles.messageText}>遇到问题，请尽管问我，我来帮你解答</div>
          </div>
        </div>

        {/* 推荐问题卡片 */}
        <div className={styles.messageGroup}>
          <div className={styles.suggestedCard}>
            <div className={styles.cardHeader}>
              <span className={styles.cardTitle}>猜你想问</span>
              <span className={styles.refreshBtn} onClick={refreshQuestions}>换一批</span>
            </div>
            <div className={styles.questionsList}>
              {suggestedQuestions.map((q, i) => (
                <div key={i} className={styles.questionItem} onClick={() => handleQuestionClick(q)}>
                  {i + 1}. {q}
                </div>
              ))}
            </div>
            <div className={styles.actionsSection}>
              <div className={styles.actionsTitle}>猜你想做</div>
              <div className={styles.actionsGrid}>
                {suggestedActions.map((a, i) => (
                  <div key={i} className={styles.actionItem} onClick={a.action}>
                    <div className={styles.actionIcon}>{a.icon}</div>
                    <div className={styles.actionText}>{a.text}</div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>

        {viewingImage && createPortal(
          <div className={styles.imageOverlay} onClick={() => setViewingImage(null)}>
            <img 
              src={viewingImage}
              className={styles.imageFullscreen}
              alt="预览图片"
              onClick={() => {
                setViewingImage(null)
                setScale(1)
                setPosition({ x: 0, y: 0 })
              }}
              style={{ transform: `scale(${scale}) translate(${position.x}px, ${position.y}px)`, transformOrigin: 'center center' }}
              onWheel={(e) => {
                e.preventDefault()
                const delta = e.deltaY > 0 ? -0.1 : 0.1
                setScale(prev => Math.max(0.5, Math.min(3, prev + delta)))
              }}
              onMouseDown={(e) => {
                if (e.button !== 0) return
                const startPos = { x: e.clientX, y: e.clientY }
                const startOffset = { ...position }
                const onMouseMove = (mv) => {
                  const dx = mv.clientX - startPos.x
                  const dy = mv.clientY - startPos.y
                  setPosition({ x: startOffset.x + dx, y: startOffset.y + dy })
                }
                const onMouseUp = () => {
                  document.removeEventListener('mousemove', onMouseMove)
                  document.removeEventListener('mouseup', onMouseUp)
                }
                document.addEventListener('mousemove', onMouseMove)
                document.addEventListener('mouseup', onMouseUp)
              }}
            />
          </div>,
          document.body
        )}

        {/* 聊天历史 */}
        {chatHistory.map((message, index) => (
          <div 
            key={index} 
            className={`${styles.messageGroup} ${message.type === 'user' ? styles.userMessage : ''}`}
          >
            <div className={`${styles.messageBubble} ${message.type === 'user' ? styles.userBubble : ''}`}>
              {message.url ? (
                <div className={`${styles.uploadBar} ${message.isAudio ? styles.voiceBubble : ''}`}>
                  {message.isAudio ? (
                    <audio src={message.url} controls />
                  ) : (message.isImage ? (
                    <div onClick={() => setViewingImage(message.url)}>
                      <img src={message.url} className={styles.imageThumbnail} alt="上传的图片" onError={(e) => { e.target.style.display = 'none' }} />
                    </div>
                  ) : (
                    <a className={styles.fileLink} href={message.url} download>
                      {message.content || '点击下载文件'}
                    </a>
                  ))}
                </div>
              ) : (
                <div className={styles.messageText}>{message.content}</div>
              )}
            </div>
          </div>
        ))}

        {isLoading && null}

        <div ref={chatEndRef} />
      </div>

      {/* 底部输入框（分为上下两行） */}
      <div className={styles.inputContainer}>
        {/* 上排：+号和表情按钮 */}
        <div className={styles.topRow}>
          <div className={styles.leftButtons}>
            <div 
              className={`${styles.funcBtn} ${showPlusMenu ? styles.active : ''}`}
              onClick={() => setShowPlusMenu(!showPlusMenu)}
              title="更多功能"
            >
              +
            </div>
            <div 
              className={styles.funcBtn}
              onClick={() => setShowEmojiMenu(!showEmojiMenu)}
              title="选择表情"
            >
              😊
            </div>
          </div>
        </div>

        {/* 下排：输入框和功能按钮 */}
        <div className={styles.bottomRow}>
          <div className={styles.inputArea}>
            {isVoiceMode ? (
              <div className={styles.voiceInput}>
                <div 
                  className={`${styles.voiceBtn} ${isRecording ? styles.recording : ''}`}
                  onClick={handleVoiceInput}
                  title={isRecording ? '点击停止录音' : '点击开始录音'}
                >
                  🎤
                </div>
                <div className={styles.voiceText}>
                  {isRecording ? '正在录音...' : '按住说话'}
                </div>
                <div 
                  className={styles.voiceToggleBtn}
                  onClick={toggleVoiceMode}
                  title="切换到键盘"
                >
                  ⌨️
                </div>
              </div>
            ) : (
              <div className={styles.textInputWrapper}>
                <input
                  type="text"
                  className={styles.textInput}
                  placeholder="请简述您的问题"
                  value={inputValue}
                  onChange={(e) => setInputValue(e.target.value)}
                  onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}
                  disabled={isLoading}
                  onFocus={handleInputFocus}
                />
                <div 
                  className={styles.voiceToggleBtn}
                  onClick={toggleVoiceMode}
                  title="切换到语音"
                >
                  🎤
                </div>
              </div>
            )}
          </div>
          
          <div className={styles.sendBtnWrapper}>
            <div 
              className={`${styles.sendBtn} ${isLoading ? styles.disabled : ''}`}
              onClick={handleSendMessage}
            >
              {isLoading ? '发送中...' : '发送'}
            </div>
          </div>
        </div>

        {/* 隐藏的文件输入 */}
        <input type="file" ref={fileInputRef} style={{ display: 'none' }} onChange={handleUpload} accept="image/*,application/pdf,application/zip,audio/*,video/*" />
        <input type="file" ref={folderInputRef} style={{ display: 'none' }} onChange={handleFolderUpload} webkitdirectory="" directory="" multiple />

        {/* + 号功能菜单 */}
        {showPlusMenu && (
          <div className={styles.plusMenu}>
            <div className={styles.menuItem} onClick={() => { fileInputRef.current?.click(); setShowPlusMenu(false) }}>
              <div className={styles.menuIcon}>📷</div>
              <div className={styles.menuText}>图片</div>
            </div>
            <div className={styles.menuItem} onClick={() => { fileInputRef.current?.click(); setShowPlusMenu(false) }}>
              <div className={styles.menuIcon}>📄</div>
              <div className={styles.menuText}>文件</div>
            </div>
            <div className={styles.menuItem} onClick={() => { folderInputRef.current?.click(); setShowPlusMenu(false) }}>
              <div className={styles.menuIcon}>📁</div>
              <div className={styles.menuText}>文件夹</div>
            </div>
            <div className={styles.menuItem} onClick={() => { setIsVoiceMode(true); setShowPlusMenu(false) }}>
              <div className={styles.menuIcon}>🎤</div>
              <div className={styles.menuText}>语音</div>
            </div>
          </div>
        )}

        {/* Emoji 选择菜单 */}
        {showEmojiMenu && (
          <div className={styles.emojiMenu}>
            {['😊', '😂', '🤔', '👍', '❤️', '😭', '😡', '🎉', '🔥', '💯', '✨', '🌟', '😎', '🤗', '😴', '🤯', '🥳', '😇', '🤠', '👻', '🤖', '👽', '🐱', '🐶', '🦄', '🌈', '⭐', '💎', '🎯', '🚀', '💪', '🧠', '💡'].map((emoji, index) => (
              <div 
                key={index} 
                className={styles.emojiItem}
                onClick={() => handleEmojiClick(emoji)}
              >
                {emoji}
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  )
}

export default CustomerService